type Widget
    protected
    Object;


type WidgetTopLevel
    protected
    Widget;

type Dialog
    protected
    WidgetTopLevel;

type Window
    protected
    WidgetTopLevel;

export function show:
    &(WidgetTopLevel) => Async
    native 'qt-show';

export function show-at-center:
    &(WidgetTopLevel) => Async
    native 'qt-show-at-center';


type BaseWebView
    protected
    Widget;

type PlainWebView
    protected
    BaseWebView;

type WebView
    protected
    BaseWebView;

function bind:
    &(WebView, Component, List[Asset]) => Async[never]
    native 'ui-bind';

export function bind:
    &(WebView, Component) => Async[never]
    &(view, root) => { bind (view, root, []) };

export function bind:
    &(WebView, { root: Component, assets: List[Asset] }) => Async[never]
    &(view, opts) =>
        let { root, assets } := opts,
        { bind (view, root, assets) };


type NativeLabel
    protected
    Widget;

export function bind:
    &(NativeLabel, Computed[String]) => Async[never]
    &(label, @text) => {
        bind-property {
            object: label,
            prop:   'text',
            type:   PropTypeString,
            source: @text
        } };


type NativeInput
    protected
    Widget;

export function bind:
    &(NativeInput, Reactive[String]) => Async[never]
    &(input, @text) => {
        bind-property {
            object: input,
            prop:   'text',
            type:   PropTypeString,
            notify: 'textEdited(const QString&)',
            sync:   @text
        } };

export function activated:
    &(NativeInput) => Source[unit]
    &(input) => { Signal (input, 'returnPressed()') };


type NativeInputMultiLine
    protected
    Widget;

export function bind:
    &(NativeInputMultiLine, Reactive[String]) => Async[never]
    &(input, @text) => {
        bind-property {
            object: input,
            prop:   'plainText',
            type:   PropTypeString,
            notify: 'textChanged()',
            sync:   @text
        } };


type NativeButton
    protected
    Widget;

export function activated:
    &(NativeButton) => Source[unit]
    &(button) => { Signal (button,'clicked()') };


type NativeCheckbox
    protected
    Widget;

export function bind:
    &(NativeCheckbox, Reactive[Bool]) => Async[never]
    &(checkbox, @checked) => {
        bind-property {
            object: checkbox,
            prop:   'checked',
            type:   PropTypeBool,
            notify: 'stateChanged(int)',
            sync:   @checked
        } };


type NativeSelect
    protected
    Widget;

export function bind:
    &(NativeSelect, Reactive[Maybe[Number]]) => Async[never]
    &(select-widget, @index) => {
        bind-property {
            object: select-widget,
            prop:   'currentIndex',
            type:   PropTypeMaybeNumber,
            notify: 'activated(int)',
            sync:   @index
        } };

// NativeList
type NativeList
    protected
    Widget;

type NativeListItem
    native;

// TODO: bind { items: Observable[FlexList[String]], current: Reactive[FlexListKey] }
/*
export function set-items:
    &(NativeList,List[NativeListItem],Maybe[String]) => Async
    native 'qt-list-widget-set-items';

export function list-widget-item:
    &(String,String) => NativeListItem
    native 'qt-list-widget-item';

export function list-widget-item:
    &(String,image::PNG,String) => NativeListItem
    native 'qt-list-widget-item-with-icon-png';

function get-current-item:
    &(Static[NativeList]) => Maybe[String]
    native 'qt-list-widget-get-current';

export function current-item:
    &(NativeList) => Observable[Maybe[String]]
    &(list) => { Signal (list,'currentRowChanged(int)',get-current-item) };
*/
